package com.hc.java.io;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/6/13 12:03
 */
public class BioServerDemo {
    public static void main(String[] args) {
        try {
            System.out.println("TCP服务端启动~~~");
            //注册端口
            ServerSocket serverSocket = new ServerSocket(9999);
            //一个服务端只需要对应一个线程池
            HandlerSocketThreadPool handlerSocketThreadPool =
                    new HandlerSocketThreadPool(3, 100);
            while (true) {
                //开始等待客户端的Socket管道连接  accept()方法，阻塞等待客户端连接
                Socket socket = serverSocket.accept();

                System.out.println("有人上线了");
                //每次接收到客户端发来的请求，就单独创建一个线程来处理
                handlerSocketThreadPool.execute(new ReaderClientRunnable(socket));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//自定义线程池
class HandlerSocketThreadPool {
    private ExecutorService executorService;

    public HandlerSocketThreadPool(int maxPoolSize, int queueSize) {
        executorService = new ThreadPoolExecutor(
                maxPoolSize,
                maxPoolSize,
                120L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(queueSize));
    }

    public void execute(Runnable task) {
        this.executorService.execute(task);
    }
}

class ReaderClientRunnable implements Runnable {
    private Socket socket;

    public ReaderClientRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            //读取一行数据
            InputStream inputStream = socket.getInputStream();
            //转成一个缓冲字符流
            Reader fr = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(fr);
            //按行读取数据
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("服务端收到" + socket.getInetAddress() + "发来的数据：" + line);
            }
        } catch (Exception e) {
            System.out.println(socket.getInetAddress() + "下线了");
        }
    }
}
